from datetime import datetime, timedelta
from typing import Optional
from datetime import datetime, timedelta
from sqlalchemy.orm import Session
from passlib.context import CryptContext
from jose import JWTError, jwt
from ..models.user import User
from ..schemas.user import UserCreate
from ..core.config import settings

pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")

class AuthService:
    def __init__(self, db: Session):
        self.db = db

    def verify_password(self, plain_password: str, hashed_password: str) -> bool:
        return pwd_context.verify(plain_password, hashed_password)

    def get_password_hash(self, password: str) -> str:
        return pwd_context.hash(password)

    def get_user_by_username(self, username: str) -> Optional[User]:
        return self.db.query(User).filter(User.username == username).first()

    def get_user_by_email(self, email: str) -> Optional[User]:
        return self.db.query(User).filter(User.email == email).first()

    def create_user(self, user: UserCreate) -> User:
        hashed_password = self.get_password_hash(user.password)
        db_user = User(
            username=user.username,
            email=user.email,
            full_name=user.full_name,
            hashed_password=hashed_password,
            department_id=user.department_id,
            is_superuser=False  # 强制所有新注册用户都是普通用户
        )
        self.db.add(db_user)
        self.db.commit()
        self.db.refresh(db_user)
        return db_user

    def ensure_only_admin_is_superuser(self) -> None:
        """确保只有admin是超级用户"""
        # 将所有非admin用户的超级用户权限撤销
        self.db.query(User).filter(
            User.username != 'admin',
            User.is_superuser == True
        ).update({User.is_superuser: False})
        self.db.commit()
        
        # 确保admin是超级用户
        admin_user = self.get_user_by_username('admin')
        if admin_user and not admin_user.is_superuser:
            admin_user.is_superuser = True
            self.db.commit()

    def authenticate_user(self, username: str, password: str) -> Optional[User]:
        user = self.get_user_by_username(username)
        if not user:
            return None
        if not self.verify_password(password, user.hashed_password):
            return None
        return user

    def create_access_token(self, data: dict, expires_delta: Optional[timedelta] = None):
        to_encode = data.copy()
        if expires_delta:
            expire = datetime.utcnow() + expires_delta
        else:
            expire = datetime.utcnow() + timedelta(minutes=15)
        to_encode.update({"exp": expire})
        encoded_jwt = jwt.encode(to_encode, settings.SECRET_KEY, algorithm=settings.ALGORITHM)
        return encoded_jwt

    def create_password_reset_token(self, email: str, expires_delta: Optional[timedelta] = None) -> str:
        """创建密码重置令牌"""
        if expires_delta:
            expire = datetime.utcnow() + expires_delta
        else:
            expire = datetime.utcnow() + timedelta(hours=1)  # 默认1小时过期
        
        to_encode = {"sub": email, "exp": expire, "type": "password_reset"}
        encoded_jwt = jwt.encode(to_encode, settings.SECRET_KEY, algorithm=settings.ALGORITHM)
        return encoded_jwt

    def verify_password_reset_token(self, token: str) -> Optional[str]:
        """验证密码重置令牌"""
        try:
            payload = jwt.decode(token, settings.SECRET_KEY, algorithms=[settings.ALGORITHM])
            email: str = payload.get("sub")
            token_type: str = payload.get("type")
            if email is None or token_type != "password_reset":
                return None
            return email
        except JWTError:
            return None

    def get_current_time(self) -> datetime:
        """获取当前时间"""
        return datetime.utcnow()